package com.terracloud.server.common.stats;

import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import io.prometheus.client.CollectorRegistry;
import io.prometheus.client.Gauge;
import io.prometheus.client.Counter;
import io.prometheus.client.exporter.PushGateway;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 设备资源监控指标服务实现
 * 负责收集设备资源使用情况并上报到PushGateway
 */
@Slf4j
public class DeviceMetricsServiceImpl implements DeviceMetricsService {

    private final StatsProperties statsProperties;
    private final PushGateway pushGateway;
    private final CollectorRegistry registry;
    
    // 设备内存指标
    private final Gauge deviceMemoryTotalBytes;
    private final Gauge deviceMemoryAvailableBytes;
    
    // 设备CPU指标
    private final Gauge deviceCpuLoadPercentage;
    
    // 设备磁盘指标
    private final Gauge deviceDiskTotalBytes;
    private final Gauge deviceDiskAvailableBytes;
    
    // 设备网络指标
    private final Gauge deviceNetworkBytesSent;
    private final Gauge deviceNetworkBytesRecv;
    
    // 设备VPN连接状态指标
    private final Gauge deviceVpnConnectionStatus;
    
    // 告警计数器指标
    private final Counter alertCounter;
    
    // 心跳计数器指标
    private final Counter heartbeatCounter;

    // 数据采集统一指标，包含所有相关信息作为标签
    private final Gauge dataCollectionMetric;
    
    // 数据交付统一指标，包含所有相关信息作为标签
    private final Gauge dataDeliveryMetrics;

    // 数据产品总量指标
    private final Gauge dataProductionTotalMetric;

    // 数据产品已用指标
    private final Gauge dataProductionUsedMetric;
    
    // 数据产品未用指标
    private final Gauge dataProductionUnusedMetric;

    // 数据资源总量指标
    private final Gauge dataSourceTotalMetric;

    // 数据资源数据库指标
    private final Gauge dataSourceDatabaseMetric;

    // 数据资源API指标
    private final Gauge dataSourceApiMetric;

    // 数据资源TXT指标
    private final Gauge dataSourceTxtMetric;
    
    // 存储设备指标的缓存，避免重复创建
    private final Map<String, Map<String, String>> deviceLabels = new ConcurrentHashMap<>();
    
    public DeviceMetricsServiceImpl(StatsProperties statsProperties) {
        this.statsProperties = statsProperties;
        // 处理PushGateway URL，移除可能的协议前缀
        String pushGatewayUrl = statsProperties.getPushGatewayUrl();
        if (pushGatewayUrl.startsWith("http://")) {
            pushGatewayUrl = pushGatewayUrl.substring(7);
        } else if (pushGatewayUrl.startsWith("https://")) {
            pushGatewayUrl = pushGatewayUrl.substring(8);
        }
        this.pushGateway = new PushGateway(pushGatewayUrl);
        this.registry = new CollectorRegistry(true);
        
        // 测试PushGateway连接
        if (statsProperties.isPushEnabled()) {
            testPushGatewayConnection();
        }
        
        // 创建设备内存指标
        this.deviceMemoryTotalBytes = Gauge.build()
                .name("device_memory_total_bytes")
                .help("Device total memory bytes")
                .labelNames("tenant_id", "device_id")
                .register(registry);
                
        this.deviceMemoryAvailableBytes = Gauge.build()
                .name("device_memory_available_bytes")
                .help("Device available memory bytes")
                .labelNames("tenant_id", "device_id")
                .register(registry);
                
        // 创建设备CPU指标
        this.deviceCpuLoadPercentage = Gauge.build()
                .name("device_cpu_load_percentage")
                .help("Device CPU load percentage")
                .labelNames("tenant_id", "device_id")
                .register(registry);
                
        // 创建设备磁盘指标
        this.deviceDiskTotalBytes = Gauge.build()
                .name("device_disk_total_bytes")
                .help("Device total disk bytes")
                .labelNames("tenant_id", "device_id")
                .register(registry);
                
        this.deviceDiskAvailableBytes = Gauge.build()
                .name("device_disk_available_bytes")
                .help("Device available disk bytes")
                .labelNames("tenant_id", "device_id")
                .register(registry);
                
        // 创建设备网络指标
        this.deviceNetworkBytesSent = Gauge.build()
                .name("device_network_bytes_down")
                .help("Device network bytes down")
                .labelNames("tenant_id", "device_id")
                .register(registry);
                
        this.deviceNetworkBytesRecv = Gauge.build()
                .name("device_network_bytes_upload")
                .help("Device network bytes upload")
                .labelNames("tenant_id", "device_id")
                .register(registry);
                
        // 创建设备VPN连接状态指标
        this.deviceVpnConnectionStatus = Gauge.build()
                .name("terra_cloud_vpn_connection_status")
                .help("Device VPN connection status (1.0 for connected, 0.0 for disconnected)")
                .labelNames("device_id", "tenant_id", "node_name")
                .register(registry);
                
        // 创建告警计数器指标
        this.alertCounter = Counter.build()
                .name("terra_cloud_alerts_cnt")
                .help("Alert counter")
                .labelNames("alert_type", "tenant_id", "device_id")
                .register(registry);
                
        // 创建心跳计数器指标
        this.heartbeatCounter = Counter.build()
                .name("terra_cloud_heartbeats_cnt")
                .help("Heartbeat counter")
                .labelNames("tenant_id", "device_id")
                .register(registry);
                
        // 创建数据采集指标 (新的统一指标方式)
        this.dataCollectionMetric = Gauge.build()
                .name("data_collection_info")
                .help("Data collection information with labels for name, status, duration, counts, etc.")
                .labelNames("device_id", "tenant_id", "name", "status", "reason", "type",
                        "starttime","totaltime","sucesstimes","falsetimes")
                .register(registry);
        
        // 创建数据交付指标
        this.dataDeliveryMetrics = Gauge.build()
                .name("data_delivery_info")
                .help("Data delivery information with labels for name, status, duration, counts, etc.")
                .labelNames("device_id", "tenant_id", "name", "result", "reason", "productid", "productname", "status",
                        "starttime","totaltime","falsetimes")
                .register(registry);

        this.dataProductionTotalMetric = Gauge.build()
                .name("data_production_total")
                .help("Data production total")
                .labelNames("device_id", "tenant_id")
                .register(registry);

        this.dataProductionUsedMetric = Gauge.build()
                .name("data_production_used")
                .help("Data production used")
                .labelNames("device_id", "tenant_id")
                .register(registry);
                
        this.dataProductionUnusedMetric = Gauge.build()
                .name("data_production_unused")
                .help("Data production unused")
                .labelNames("device_id", "tenant_id")
                .register(registry);

        this.dataSourceTotalMetric = Gauge.build()
                .name("data_source_total")
                .help("Data source total")
                .labelNames("device_id", "tenant_id")
                .register(registry);

        this.dataSourceDatabaseMetric = Gauge.build()
                .name("data_source_database")
                .help("Data source database")
                .labelNames("device_id", "tenant_id")
                .register(registry);

        this.dataSourceApiMetric = Gauge.build()
                .name("data_source_api")
                .help("Data source api")
                .labelNames("device_id", "tenant_id")
                .register(registry);

        this.dataSourceTxtMetric = Gauge.build()
                .name("data_source_txt")
                .help("Data source txt")
                .labelNames("device_id", "tenant_id")
                .register(registry);
    }

    /**
     * 上报设备资源指标到PushGateway
     *
     * @param tenantId 租户ID
     * @param deviceId 设备ID
     * @param memoryTotalBytes 内存总量(bytes)
     * @param memoryAvailableBytes 可用内存量(bytes)
     * @param cpuLoadPercentage CPU负载百分比
     * @param diskTotalBytes 磁盘总量(bytes)
     * @param diskAvailableBytes 可用磁盘空间(bytes)
     * @param networkBytesSent 网络发送字节数
     * @param networkBytesRecv 网络接收字节数
     */
    @Override
    public void reportDeviceMetrics(String tenantId, String deviceId,
                                   Long memoryTotalBytes, Long memoryAvailableBytes,
                                   Double cpuLoadPercentage,
                                   Long diskTotalBytes, Long diskAvailableBytes,
                                   Long networkBytesSent, Long networkBytesRecv) {
        if (!statsProperties.isPushEnabled()) {
            log.debug("设备指标收集功能未启用");
            return;
        }
        
        try {
            // 更新标签信息
            updateDeviceLabels(tenantId, deviceId);
            
            log.debug("开始设置设备{}的指标值", deviceId);
            log.debug("memoryTotalBytes: {}, memoryAvailableBytes: {}", memoryTotalBytes, memoryAvailableBytes);
            log.debug("cpuLoadPercentage: {}", cpuLoadPercentage);
            log.debug("diskTotalBytes: {}, diskAvailableBytes: {}", diskTotalBytes, diskAvailableBytes);
            log.debug("networkBytesSent: {}, networkBytesRecv: {}", networkBytesSent, networkBytesRecv);
            
            // 设置各项指标值
            if (memoryTotalBytes != null) {
                this.deviceMemoryTotalBytes.labels(tenantId, deviceId).set(memoryTotalBytes);
                log.debug("已设置设备{}的内存总量指标: {}", deviceId, memoryTotalBytes);
            }
            
            if (memoryAvailableBytes != null) {
                this.deviceMemoryAvailableBytes.labels(tenantId, deviceId).set(memoryAvailableBytes);
                log.debug("已设置设备{}的可用内存指标: {}", deviceId, memoryAvailableBytes);
            }
            
            if (cpuLoadPercentage != null) {
                this.deviceCpuLoadPercentage.labels(tenantId, deviceId).set(cpuLoadPercentage);
                log.debug("已设置设备{}的CPU负载指标: {}", deviceId, cpuLoadPercentage);
            }
            
            if (diskTotalBytes != null) {
                this.deviceDiskTotalBytes.labels(tenantId, deviceId).set(diskTotalBytes);
                log.debug("已设置设备{}的磁盘总量指标: {}", deviceId, diskTotalBytes);
            }
            
            if (diskAvailableBytes != null) {
                this.deviceDiskAvailableBytes.labels(tenantId, deviceId).set(diskAvailableBytes);
                log.debug("已设置设备{}的可用磁盘指标: {}", deviceId, diskAvailableBytes);
            }
            
            if (networkBytesSent != null) {
                this.deviceNetworkBytesSent.labels(tenantId, deviceId).set(networkBytesSent);
                log.debug("已设置设备{}的网络发送字节指标: {}", deviceId, networkBytesSent);
            }
            
            if (networkBytesRecv != null) {
                this.deviceNetworkBytesRecv.labels(tenantId, deviceId).set(networkBytesRecv);
                log.debug("已设置设备{}的网络接收字节指标: {}", deviceId, networkBytesRecv);
            }


            // 上报心跳次数
            reportHeartbeat(tenantId, deviceId);
            
            // 推送到PushGateway
            log.debug("准备推送设备{}的指标到PushGateway", deviceId);
            pushDeviceMetrics(deviceId);
            log.info("设备{}的资源指标上报成功", deviceId);
        } catch (Exception e) {
            log.error("设备{}资源指标上报失败，错误信息: {}", deviceId, e.getMessage(), e);
            // 上报心跳异常警告
            reportHeartbeatError(tenantId, deviceId);
        }
    }

    /**
     * 上报设备VPN连接状态指标
     *
     * @param deviceId 设备ID
     * @param tenantId 租户ID
     * @param nodeName 节点名称
     * @param connected VPN连接状态 (true表示连接，false表示断开)
     */
    @Override
    public void reportDeviceVpnConnectionStatus(String deviceId, String tenantId, String nodeName, boolean connected) {
        if (!statsProperties.isPushEnabled()) {
            log.debug("设备指标收集功能未启用 (VPN连接状态指标)");
            return;
        }
        
        try {
            double statusValue = connected ? 1.0 : 0.0;
            log.debug("开始设置设备{}的VPN连接状态指标值", deviceId);
            log.debug("connected: {}", connected);
            
            // 设置VPN连接状态指标值
            this.deviceVpnConnectionStatus.labels(deviceId, tenantId, nodeName).set(statusValue);
            log.debug("已设置设备{}的VPN连接状态指标: {}", deviceId, statusValue);

            // 推送到PushGateway
            log.debug("准备推送设备{}的VPN连接状态指标到PushGateway", deviceId);
            pushDeviceMetrics(deviceId);
            log.info("设备{}的VPN连接状态指标上报成功", deviceId);
        } catch (Exception e) {
            log.error("设备{}VPN连接状态指标上报失败，错误信息: {}", deviceId, e.getMessage(), e);
            // 上报心跳异常警告
            reportHeartbeatError(tenantId, deviceId);
        }
    }


    /**
     * 上报心跳次数
     *
     * @param tenantId 租户ID
     * @param deviceId 设备ID
     */
    @Override
    public void reportHeartbeat(String tenantId, String deviceId) {
        if (!statsProperties.isPushEnabled()) {
            log.debug("设备指标收集功能未启用 (心跳次数)");
            return;
        }
        
        try {
            // 增加心跳计数
            this.heartbeatCounter.labels(tenantId, deviceId).inc();
            log.debug("已增加设备{}的心跳计数", deviceId);
            
            // 推送到PushGateway
            log.debug("准备推送心跳计数指标到PushGateway");
            pushDeviceMetrics(deviceId);
            log.debug("设备{}的心跳计数指标上报成功", deviceId);
        } catch (Exception e) {
            log.error("设备{}心跳计数指标上报失败，错误信息: {}", deviceId, e.getMessage(), e);
        }
    }
    
    /**
     * 上报心跳异常警告
     *
     * @param tenantId 租户ID
     * @param deviceId 设备ID
     */
    @Override
    public void reportHeartbeatError(String tenantId, String deviceId) {
        if (!statsProperties.isPushEnabled()) {
            log.debug("设备指标收集功能未启用 (心跳异常警告)");
            return;
        }
        
        try {
            // 增加心跳异常计数
            this.alertCounter.labels("heartbeat_error", tenantId, deviceId).inc();
            log.warn("已增加设备{}的心跳异常计数", deviceId);
            
            // 推送到PushGateway
            log.debug("准备推送心跳异常计数指标到PushGateway");
            pushDeviceMetrics(deviceId);
            log.warn("设备{}的心跳异常计数指标上报成功", deviceId);
        } catch (Exception e) {
            log.error("设备{}心跳异常计数指标上报失败，错误信息: {}", deviceId, e.getMessage(), e);
        }
    }
    
    /**
     * 上报数据采集相关指标
     *
     * @param deviceId 设备ID
     * @param tenantId 租户ID
     * @param inputs 数据采集信息数组
     */
    @Override
    public void reportDataCollectionMetrics(String deviceId, String tenantId, JsonArray inputs) {
        if (!statsProperties.isPushEnabled()) {
            log.debug("设备指标收集功能未启用 (数据采集指标)");
            return;
        }
        
        try {
            log.debug("开始设置设备{}的数据采集指标值", deviceId);
            
            // 遍历输入数组中的每个数据项
            for (int i = 0; i < inputs.size(); i++) {
                JsonObject inputObj = inputs.get(i).getAsJsonObject();
                
                String name = getStringValue(inputObj, "name");
                String startTime = getStringValue(inputObj, "starttime");
                String status = getStringValue(inputObj, "status");
                String totalTime = getStringValue(inputObj, "totaltime");
                String falseTimes = getStringValue(inputObj, "falsetimes");
                String successTimes = getStringValue(inputObj, "successtimes");
                String reason = getStringValue(inputObj, "reason");
                String type = getStringValue(inputObj, "type");
                
                // 解析时长（假设格式为 "X分钟"、"X小时" 等）
                double durationSeconds = parseDurationToSeconds(totalTime);

                // 使用新的统一指标方式上报数据采集信息，增加type标签
                // status标签直接存原始值，不做解析
                this.dataCollectionMetric.labels(deviceId, tenantId, name, status, 
                    reason != null ? reason : "", type, startTime, totalTime, successTimes, falseTimes).set(durationSeconds);
            }
            
            log.debug("已设置设备{}的所有数据采集指标", deviceId);
            
            // 推送到PushGateway
            log.debug("准备推送设备{}的数据采集指标到PushGateway", deviceId);
            pushDeviceMetrics(deviceId);
            log.info("设备{}的数据采集指标上报成功", deviceId);
        } catch (Exception e) {
            log.error("设备{}数据采集指标上报失败，错误信息: {}", deviceId, e.getMessage(), e);
        }
    }
    
    /**
     * 上报数据交付相关指标
     *
     * @param deviceId 设备ID
     * @param tenantId 租户ID
     * @param outputs 数据交付信息数组
     */
    @Override
    public void reportDataDeliveryMetrics(String deviceId, String tenantId, JsonArray outputs) {
        if (!statsProperties.isPushEnabled()) {
            log.debug("设备指标收集功能未启用 (数据交付指标)");
            return;
        }

        try {
            log.debug("开始设置设备{}的数据交付指标值", deviceId);
            
            // 遍历输出数组中的每个数据项
            for (int i = 0; i < outputs.size(); i++) {
                JsonObject outputObj = outputs.get(i).getAsJsonObject();
                
                String name = getStringValue(outputObj, "name");
                String startTime = getStringValue(outputObj, "starttime");
                String result = getStringValue(outputObj, "result");
                String totalTime = getStringValue(outputObj, "totaltime");
                String falseTimes = getStringValue(outputObj, "falsetimes");
                String reason = getStringValue(outputObj, "reason");
                String productId = getStringValue(outputObj, "productid");
                String productName = getStringValue(outputObj, "productname");
                String status = getStringValue(outputObj, "status");
                
                // 解析时长（假设格式为 "X分钟"、"X小时" 等）
                double durationSeconds = parseDurationToSeconds(totalTime);
                
                // 解析失败次数
                parseIntOrDefault(falseTimes);

                // 使用新的统一指标方式上报数据交付信息
                // 所有字段都直接使用原始值，不做解析
                this.dataDeliveryMetrics.labels(deviceId, tenantId, name, result, 
                    reason != null ? reason : "", productId, productName, status,
                    startTime, totalTime, falseTimes).set(durationSeconds);
            }

            log.debug("已设置设备{}的所有数据交付指标", deviceId);

            // 推送到PushGateway
            log.debug("准备推送设备{}的数据交付指标到PushGateway", deviceId);
            pushDeviceMetrics(deviceId);
            log.info("设备{}的数据交付指标上报成功", deviceId);
        } catch (Exception e) {
            log.error("设备{}数据交付指标上报失败，错误信息: {}", deviceId, e.getMessage(), e);
        }
    }
    
    @Override
    public void reportDataProductMetrics(String deviceId, String tenantId, int total, int used, int unused) {
        if (!statsProperties.isPushEnabled()) {
            log.debug("设备指标收集功能未启用 (数据产品指标)");
            return;
        }

        try {
            log.debug("开始设置设备{}的数据产品指标值: total={}, used={}, unused={}", deviceId, total, used, unused);

            // 设置数据产品指标值
            this.dataProductionTotalMetric.labels(deviceId, tenantId).set(total);
            this.dataProductionUsedMetric.labels(deviceId, tenantId).set(used);
            this.dataProductionUnusedMetric.labels(deviceId, tenantId).set(unused);
            
            log.debug("已设置设备{}的数据产品指标", deviceId);

            // 推送到PushGateway
            log.debug("准备推送设备{}的数据产品指标到PushGateway", deviceId);
            pushDeviceMetrics(deviceId);
            log.info("设备{}的数据产品指标上报成功", deviceId);
        } catch (Exception e) {
            log.error("设备{}数据产品指标上报失败，错误信息: {}", deviceId, e.getMessage(), e);
        }
    }
    
    @Override
    public void reportDataSourceMetrics(String deviceId, String tenantId, int total, int database, int api, int txt) {
        if (!statsProperties.isPushEnabled()) {
            log.debug("设备指标收集功能未启用 (数据资源指标)");
            return;
        }

        try {
            log.debug("开始设置设备{}的数据资源指标值: total={}, database={}, api={}, txt={}", deviceId, total, database, api, txt);

            // 设置数据资源指标值
            this.dataSourceTotalMetric.labels(deviceId, tenantId).set(total);
            this.dataSourceDatabaseMetric.labels(deviceId, tenantId).set(database);
            this.dataSourceApiMetric.labels(deviceId, tenantId).set(api);
            this.dataSourceTxtMetric.labels(deviceId, tenantId).set(txt);
            
            log.debug("已设置设备{}的数据资源指标", deviceId);

            // 推送到PushGateway
            log.debug("准备推送设备{}的数据资源指标到PushGateway", deviceId);
            pushDeviceMetrics(deviceId);
            log.info("设备{}的数据资源指标上报成功", deviceId);
        } catch (Exception e) {
            log.error("设备{}数据资源指标上报失败，错误信息: {}", deviceId, e.getMessage(), e);
        }
    }

    /**
     * 将时长字符串解析为秒数
     * 支持格式如 "15分钟", "2小时" 等
     * 
     * @param duration 时长字符串
     * @return 秒数
     */
    private double parseDurationToSeconds(String duration) {
        if (duration == null || duration.isEmpty()) {
            return 0.0;
        }
        
        try {
            // 提取数字部分
            String numberPart = duration.replaceAll("[^0-9.]", "");
            double value = Double.parseDouble(numberPart);
            
            // 根据单位转换为秒
            if (duration.contains("小时") || duration.contains("h") || duration.contains("hour")) {
                return value * 3600; // 小时转秒
            } else if (duration.contains("分钟") || duration.contains("min") || duration.contains("minute")) {
                return value * 60; // 分钟转秒
            } else if (duration.contains("秒") || duration.contains("s") || duration.contains("second")) {
                return value; // 秒
            } else {
                // 默认认为是秒
                return value;
            }
        } catch (NumberFormatException e) {
            log.warn("无法解析时长字符串: {}", duration);
            return 0.0;
        }
    }
    
    /**
     * 将字符串解析为整数
     *
     * @param str 字符串
     * @return 整数值
     */
    private int parseIntOrDefault(String str) {
        if (str == null || str.isEmpty()) {
            return 0;
        }
        
        try {
            return Integer.parseInt(str);
        } catch (NumberFormatException e) {
            log.warn("无法解析整数字符串: {}", str);
            return 0;
        }
    }
    
    /**
     * 更新设备标签信息
     * 
     * @param tenantId 租户ID
     * @param deviceId 设备ID
     */
    private void updateDeviceLabels(String tenantId, String deviceId) {
        Map<String, String> labels = new HashMap<>();
        labels.put("tenant_id", tenantId);
        labels.put("device_id", deviceId);
        deviceLabels.put(deviceId, labels);
    }

    /**
     * 测试PushGateway连接状态
     */
    public void testPushGatewayConnection() {
        try {
            String pushGatewayUrl = statsProperties.getPushGatewayUrl();
            // 确保URL格式正确
            if (!pushGatewayUrl.startsWith("http://") && !pushGatewayUrl.startsWith("https://")) {
                pushGatewayUrl = "http://" + pushGatewayUrl;
            }
            
            URL url = new URL(pushGatewayUrl + "/-/healthy");
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("GET");
            connection.setConnectTimeout(5000); // 5秒连接超时
            connection.setReadTimeout(5000);    // 5秒读取超时
            
            int responseCode = connection.getResponseCode();
            if (responseCode == 200) {
            } else {
                log.warn("PushGateway连接测试失败，HTTP响应码: {}", responseCode);
            }
        } catch (Exception e) {
            log.error("PushGateway连接测试异常: {}", e.getMessage(), e);
        }
    }

    /**
     * 上报设备指标到PushGateway
     *
     * @param deviceId 设备ID
     * @throws IOException 上报过程中发生IO异常
     */
    private void pushDeviceMetrics(String deviceId) throws IOException {
        Map<String, String> groupingKey = new HashMap<>();
        groupingKey.put("instance", deviceId);
        groupingKey.put("job", "device_metrics");
        
        // 添加重试机制
        int maxRetries = 3;
        IOException lastException = null;
        
        for (int i = 0; i < maxRetries; i++) {
            try {
                pushGateway.pushAdd(registry, "device_metrics", groupingKey);
                log.info("成功将设备{}的指标推送到PushGateway: http://{}/metrics/job/{}/instance/{}",
                        deviceId, statsProperties.getPushGatewayUrl(), "device_metrics", deviceId);
                return; // 成功推送后直接返回
            } catch (IOException e) {
                lastException = e;
                log.warn("第{}次推送设备{}指标到PushGateway失败: {}", i + 1, deviceId, e.getMessage());
                if (i < maxRetries - 1) {
                    // 等待一段时间后重试
                    try {
                        Thread.sleep(1000 * (i + 1)); // 逐步增加等待时间
                    } catch (InterruptedException ie) {
                        Thread.currentThread().interrupt();
                        throw new IOException("推送过程中线程被中断", ie);
                    }
                }
            }
        }
        
        // 如果所有重试都失败了，抛出最后一次异常
        throw new IOException("推送设备" + deviceId + "指标到PushGateway失败，已重试" + maxRetries + "次", lastException);
    }

    /**
     * 从JsonObject中安全获取字符串值
     *
     * @param obj JsonObject对象
     * @param fieldName 字段名
     * @return 字段值或空字符串
     */
    private String getStringValue(JsonObject obj, String fieldName) {
        if (obj.has(fieldName) && obj.get(fieldName).isJsonPrimitive()) {
            return obj.get(fieldName).getAsString();
        }
        log.debug("字段 {} 不存在或不是基本类型，返回空字符串", fieldName);
        return "";
    }
    
}